package com.panfeng.xcloud.common.security.feign;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 *
 * feignOAuth2请求拦截器
 *
 * @author xiaobo
 * @version 1.0
 * @since 2018-12-28
 */
@Slf4j
public class FeignOAuth2RequestInterceptor implements RequestInterceptor {

	private final OAuth2RestTemplate oAuth2RestTemplate;

	public FeignOAuth2RequestInterceptor(OAuth2RestTemplate oAuth2RestTemplate) {
		Assert.notNull(oAuth2RestTemplate, "oAuth2RestTemplate 不能为空");
		this.oAuth2RestTemplate = oAuth2RestTemplate;
	}

	@Override
	public void apply(RequestTemplate template) {
		HttpServletRequest httpServletRequest =   getHttpServletRequest();
		if(httpServletRequest!=null){
			Map<String, String> headers = getHeaders(httpServletRequest);
			// 传递所有请求头,防止部分丢失
			for (Map.Entry<String, String> entry : headers.entrySet()) {
				template.header(entry.getKey(), entry.getValue());
			}
			log.info(">>> feign api 调用时传递的header类型: {}, token类型:{}", HttpHeaders.AUTHORIZATION, FeignConstants.BEARER_TOKEN_TYPE);
			log.debug("FeignRequestInterceptor:{}", template.toString());
		}
	}

	private HttpServletRequest getHttpServletRequest() {
		try {
			return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 获取原请求头
	 */
	private Map<String, String> getHeaders(HttpServletRequest request) {
		Map<String, String> map = new LinkedHashMap<>();
		Enumeration<String> enumeration = request.getHeaderNames();
		if(enumeration!=null){
			while (enumeration.hasMoreElements()) {
				String key = enumeration.nextElement();
				String value = request.getHeader(key);
				map.put(key, value);
			}
		}
		return map;
	}

}
